package org.acghub.mtdb.common;

import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;

/**
 * @author zhouhe
 */
public class Root extends Naming {

    /**
     * 默认根节点
     */
    public static final Root DEFAULT_ROOT = new Root();

    private int count;

    public Root() {
        super();
        this.setResolved(true);
    }

    private final NavigableMap<String[], Naming> symbols = new TreeMap<>((o1, o2) -> {
        int l1 = o1.length, l2 = o2.length, c;
        while (true) {
            if ((c = o1[--l1].compareTo(o2[--l2])) != 0 || l1 <= 0 || l2 <= 0) {
                break;
            }
        }
        return c != 0 ? c : l1 - l2;
    });

    public int incr() {
        return ++count;
    }

    public NavigableMap<String[], Naming> getSymbols() {
        return symbols;
    }

    public void addSymbol(String[] name, Naming naming) {
        symbols.put(name, naming);
    }

    @Override
    public <T extends Naming> T search(String[] ref, Class<T> clazz) {
        T t = null;
        for (Map.Entry<String[], Naming> e : symbols.tailMap(ref).entrySet()) {
            String[] key = e.getKey();
            int l1 = ref.length;
            int l2 = key.length;
            int c;
            while (true) {
                if ((c = ref[--l1].compareTo(key[--l2])) != 0 || l1 <= 0 || l2 <= 0) {
                    break;
                }
            }
            if (c != 0 || l1 != 0) {
                break;
            }
            Naming n = e.getValue();
            if (n.isResolved() && clazz.isInstance(n)) {
                if (t != null) {
                    this.dump(System.err);
                    throw new RuntimeException("Ambiguous symbol\n" + t + "\r------------------\n\n" + n);
                }
                t = clazz.cast(n);
            }
        }
        return t;
    }
}
